<?php

namespace App\Http\Controllers\Api\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Requests\Tenant\NotificationMarkRequest;
use App\Models\TenantNotificationLog;
use App\Models\TenantNotificationReceipt;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class NotificationLogController extends Controller
{
    public function index(Request $request): JsonResponse
    {
        $tenant = $request->attributes->get('tenant') ?? $request->user()?->tenant;

        if (! $tenant) {
            return response()->json([
                'error' => [
                    'code' => 'tenant_context_missing',
                    'title' => 'Tenant context missing',
                    'message' => 'Unable to resolve tenant for notification logs.',
                ],
            ], 403);
        }

        $user = $request->user();

        $query = TenantNotificationLog::query()
            ->where('tenant_id', $tenant->id)
            ->with('receipts')
            ->latest();

        if ($type = $request->query('type')) {
            $query->where('type', $type);
        }

        if ($status = $request->query('status')) {
            $query->where('status', $status);
        }

        if ($scope = $request->query('scope')) {
            $query->where(function (Builder $inner) use ($scope) {
                $inner->where('type', $scope)
                    ->orWhere(function (Builder $ctx) use ($scope) {
                        $ctx->whereJsonContains('context->scope', $scope);
                    });
            });
        }

        if ($eventId = $request->query('event_id')) {
            $query->where(function (Builder $inner) use ($eventId) {
                $inner->where('context->event_id', (int) $eventId)
                    ->orWhere('context->eventId', (int) $eventId);
            });
        }

        $perPage = (int) $request->query('per_page', 20);
        $perPage = max(1, min($perPage, 100));

        $logs = $query->paginate($perPage);

        $receipts = collect($logs->items())
            ->map(fn ($log) => $log->receipts ?? collect())
            ->flatten();

        $unreadCount = $receipts
            ->filter(fn ($receipt) => $user && $receipt->user_id === $user->id && $receipt->status !== 'read')
            ->count();

        $data = collect($logs->items())->map(function (TenantNotificationLog $log) use ($user) {
            $receipt = $user
                ? $log->receipts->firstWhere('user_id', $user->id)
                : null;

            return array_merge($log->toArray(), [
                'is_read' => $receipt ? $receipt->status === 'read' : false,
            ]);
        })->all();

        return response()->json([
            'data' => $data,
            'meta' => [
                'current_page' => $logs->currentPage(),
                'last_page' => $logs->lastPage(),
                'per_page' => $logs->perPage(),
                'total' => $logs->total(),
                'unread_count' => $unreadCount,
            ],
        ]);
    }

    public function mark(NotificationMarkRequest $request): JsonResponse
    {
        $tenant = $request->attributes->get('tenant') ?? $request->user()?->tenant;

        if (! $tenant) {
            return response()->json([
                'error' => [
                    'code' => 'tenant_context_missing',
                    'title' => 'Tenant context missing',
                    'message' => 'Unable to resolve tenant for notification logs.',
                ],
            ], 403);
        }

        $userId = $request->user()?->id;
        $status = $request->validated('status');
        $ids = $request->validated('ids');

        TenantNotificationReceipt::query()
            ->where('tenant_id', $tenant->id)
            ->whereIn('notification_log_id', $ids)
            ->when($userId, fn ($q) => $q->where(function ($inner) use ($userId) {
                $inner->whereNull('user_id')->orWhere('user_id', $userId);
            }))
            ->update(['status' => $status]);

        return response()->json([
            'message' => 'Notifications updated.',
        ]);
    }
}
