<?php

namespace App\Http\Controllers\Api\V1;

use App\Domain\Notification\Enums\NotificationChannel;
use App\Domain\Notification\Enums\NotificationStatus;
use App\Domain\Notification\Models\NotificationLog;
use App\Domain\Notification\Models\NotificationPreference;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

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

        $notifications = NotificationLog::where('recipient_type', 'user')
            ->where('recipient_id', $user->id)
            ->whereIn('channel', [
                NotificationChannel::InApp->value,
                NotificationChannel::Push->value,
            ])
            ->orderByDesc('created_at')
            ->paginate(20);

        return response()->json([
            'data' => $notifications->map(fn ($n) => [
                'id' => $n->id,
                'event_type' => $n->event_type,
                'title' => $n->subject,
                'body' => $n->body,
                'is_read' => $n->read_at !== null,
                'read_at' => $n->read_at?->toIso8601String(),
                'sent_at' => $n->sent_at?->toIso8601String(),
                'created_at' => $n->created_at?->toIso8601String(),
                'metadata' => $n->metadata,
            ]),
            'unread_count' => NotificationLog::where('recipient_type', 'user')
                ->where('recipient_id', $user->id)
                ->whereIn('channel', [
                    NotificationChannel::InApp->value,
                    NotificationChannel::Push->value,
                ])
                ->where('status', NotificationStatus::Sent)
                ->whereNull('read_at')
                ->count(),
            'meta' => [
                'current_page' => $notifications->currentPage(),
                'last_page' => $notifications->lastPage(),
                'per_page' => $notifications->perPage(),
                'total' => $notifications->total(),
            ],
        ]);
    }

    public function markAsRead(int $id, Request $request): JsonResponse
    {
        $user = $request->user();

        $notification = NotificationLog::where('id', $id)
            ->where('recipient_type', 'user')
            ->where('recipient_id', $user->id)
            ->firstOrFail();

        if (!$notification->read_at) {
            $notification->update(['read_at' => now()]);
        }

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

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

        NotificationLog::where('recipient_type', 'user')
            ->where('recipient_id', $user->id)
            ->whereIn('channel', [
                NotificationChannel::InApp->value,
                NotificationChannel::Push->value,
            ])
            ->whereNull('read_at')
            ->update(['read_at' => now()]);

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

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

        $prefs = NotificationPreference::where('user_id', $user->id)->get();

        return response()->json([
            'data' => $prefs->map(fn ($p) => [
                'event_type' => $p->event_type,
                'channel_email' => (bool) $p->channel_email,
                'channel_sms' => (bool) $p->channel_sms,
                'channel_push' => (bool) ($p->channel_push ?? true),
                'digest_mode' => (bool) $p->digest_mode,
            ]),
        ]);
    }

    public function updatePreferences(Request $request): JsonResponse
    {
        $request->validate([
            'preferences' => 'required|array',
            'preferences.*.event_type' => 'required|string',
            'preferences.*.channel_push' => 'boolean',
            'preferences.*.channel_email' => 'boolean',
            'preferences.*.channel_sms' => 'boolean',
        ]);

        $user = $request->user();

        foreach ($request->preferences as $pref) {
            NotificationPreference::updateOrCreate(
                ['user_id' => $user->id, 'event_type' => $pref['event_type']],
                [
                    'channel_email' => $pref['channel_email'] ?? true,
                    'channel_sms' => $pref['channel_sms'] ?? true,
                    'channel_push' => $pref['channel_push'] ?? true,
                ]
            );
        }

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