<?php

namespace App\Http\Controllers\Api\Tenant;

use App\Http\Controllers\Controller;
use App\Http\Resources\Tenant\TaskCollectionResource;
use App\Models\Event;
use App\Models\TaskCollection;
use App\Models\Tenant;
use App\Services\Tenant\TaskCollectionImportService;
use App\Support\TenantRequestResolver;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Validation\Rule;

class TaskCollectionController extends Controller
{
    public function index(Request $request): AnonymousResourceCollection
    {
        $tenantId = $this->currentTenant($request)->id;

        $query = TaskCollection::query()
            ->forTenant($tenantId)
            ->with('eventType')
            ->withCount(['tasks', 'events'])
            ->orderBy('position')
            ->orderBy('id');

        if ($search = $request->query('search')) {
            $query->where(function ($inner) use ($search) {
                $inner->where('name_translations->de', 'like', "%{$search}%")
                    ->orWhere('name_translations->en', 'like', "%{$search}%");
            });
        }

        if ($eventTypeSlug = $request->query('event_type')) {
            $query->whereHas('eventType', fn ($q) => $q->where('slug', $eventTypeSlug));
        }

        if ($request->boolean('only_global')) {
            $query->whereNull('tenant_id');
        }

        if ($request->boolean('only_tenant')) {
            $query->where('tenant_id', $tenantId);
        }

        if ($request->boolean('top_picks')) {
            if ($eventTypeSlug = $request->query('event_type')) {
                $query->where(function ($inner) use ($eventTypeSlug) {
                    $inner->whereNull('event_type_id')
                        ->orWhereHas('eventType', fn ($q) => $q->where('slug', $eventTypeSlug));
                });
            }

            $query->whereHas('tasks')
                ->orderByDesc('events_count')
                ->orderByDesc('updated_at')
                ->orderBy('position')
                ->orderBy('id');

            $limit = $request->integer('limit', 3);

            return TaskCollectionResource::collection(
                $query->limit($limit)->get()
            );
        }

        $perPage = $request->integer('per_page', 15);

        return TaskCollectionResource::collection(
            $query->paginate($perPage)
        );
    }

    public function show(Request $request, TaskCollection $collection): JsonResponse
    {
        $this->authorizeAccess($request, $collection);

        $collection->load(['eventType', 'tasks' => fn ($query) => $query->with('assignedEvents')])
            ->loadCount(['tasks', 'events']);

        return response()->json(new TaskCollectionResource($collection));
    }

    public function activate(
        Request $request,
        TaskCollection $collection,
        TaskCollectionImportService $importService
    ): JsonResponse {
        $this->authorizeAccess($request, $collection);

        $data = $request->validate([
            'event_slug' => ['required', 'string', Rule::exists('events', 'slug')->where('tenant_id', $this->currentTenant($request)->id)],
        ]);

        $event = Event::where('slug', $data['event_slug'])
            ->where('tenant_id', $this->currentTenant($request)->id)
            ->firstOrFail();

        $result = $importService->import($collection, $event);

        return response()->json([
            'message' => __('Task-Collection erfolgreich importiert.'),
            'collection' => new TaskCollectionResource(
                $result['collection']
                    ->load('eventType')
                    ->loadCount(['tasks', 'events'])
            ),
            'created_task_ids' => $result['created_task_ids'],
            'attached_task_ids' => $result['attached_task_ids'],
        ]);
    }

    protected function authorizeAccess(Request $request, TaskCollection $collection): void
    {
        if ($collection->tenant_id && $collection->tenant_id !== $this->currentTenant($request)->id) {
            abort(404);
        }
    }

    protected function currentTenant(Request $request): Tenant
    {
        return TenantRequestResolver::resolve($request);
    }
}
