<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Http\Requests\BulkProjectActionRequest;
use App\Http\Requests\StoreProjectRequest;
use App\Http\Requests\UpdateProjectRequest;
use App\Http\Resources\ProjectResource;
use App\Models\Project;
use App\Services\Project\ProjectService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

/**
 * Проекты tenant'а — расширенный API для ProjectsView + NewDealDialog.
 *
 * index: фильтры по signal_type/status/search, пагинация, batch-fetch по ids.
 * show:  детальная карточка проекта с supplier_links.
 *
 * Auth: auth:sanctum + tenant middleware (устанавливает app.current_tenant_id для RLS).
 * Task 2 Plan 5 заменяет MVP-версию (tenant_id параметром, без auth).
 */
class ProjectController extends Controller
{
    public function __construct(private readonly ProjectService $projects) {}

    /** GET /api/projects */
    public function index(Request $request): JsonResponse
    {
        $query = Project::query()
            ->with(['supplierB1', 'supplierB2', 'supplierB3']) // eager-load to avoid N+1 in aggregation helpers
            ->where('tenant_id', $request->user()->tenant_id);

        // Batch-fetch по ids — возвращает без пагинации (для dropdown'ов и т.п.)
        if ($ids = $request->query('ids')) {
            // '?ids=' batch fetch. Non-numeric and zero values silently dropped via intval+filter
            // (intval('abc')=0 → array_filter drops 0). Acceptable for a read-only dropdown:
            // invalid input produces empty result, not 422.
            $idArray = array_filter(array_map('intval', explode(',', (string) $ids)));
            $items = $query->whereIn('id', $idArray)->get();

            return response()->json(['data' => ProjectResource::collection($items)]);
        }

        // Фильтр по типу сигнала
        if ($type = $request->query('signal_type')) {
            $query->where('signal_type', $type);
        }

        // Фильтр по статусу жизненного цикла
        $status = $request->query('status');
        if ($status === 'archived') {
            $query->archived();
        } elseif ($status === 'active') {
            $query->active()->where('is_active', true);
        } elseif ($status === 'paused') {
            $query->active()->where('is_active', false);
        } else {
            // По умолчанию: все не архивированные (active + paused)
            $query->active();
        }

        // Поиск по name и signal_identifier
        if ($search = $request->query('search')) {
            $query->where(function ($q) use ($search) {
                $q->where('name', 'ilike', "%{$search}%")
                    ->orWhere('signal_identifier', 'ilike', "%{$search}%");
            });
        }

        $perPage = min((int) $request->query('per_page', '20'), 100);
        $projects = $query->orderBy('created_at', 'desc')->paginate($perPage);

        return response()->json([
            'data' => ProjectResource::collection($projects->items()),
            'meta' => [
                'current_page' => $projects->currentPage(),
                'per_page' => $projects->perPage(),
                'total' => $projects->total(),
            ],
        ]);
    }

    /** POST /api/projects */
    public function store(StoreProjectRequest $request): JsonResponse
    {
        $project = $this->projects->create($request->user()->tenant, $request->validated());

        return response()->json(['data' => new ProjectResource($project)], 201);
    }

    /** PATCH /api/projects/{id} */
    public function update(UpdateProjectRequest $request, int $id): JsonResponse
    {
        $project = Project::where('tenant_id', $request->user()->tenant_id)->findOrFail($id);
        $updated = $this->projects->update($project, $request->validated());

        return response()->json(['data' => new ProjectResource($updated)]);
    }

    /** GET /api/projects/{id} */
    public function show(Request $request, int $id): JsonResponse
    {
        $project = Project::with(['supplierB1', 'supplierB2', 'supplierB3']) // eager-load to avoid N+1
            ->where('tenant_id', $request->user()->tenant_id)
            ->findOrFail($id);

        return response()->json(['data' => new ProjectResource($project)]);
    }

    /** DELETE /api/projects/{id} — soft-archive (sets archived_at, is_active=false) */
    public function destroy(Request $request, int $id): JsonResponse
    {
        $project = Project::where('tenant_id', $request->user()->tenant_id)->findOrFail($id);
        $this->projects->archive($project);

        return response()->json(null, 204);
    }

    /** POST /api/projects/{id}/sync — re-dispatch SyncSupplierProjectJob */
    public function sync(Request $request, int $id): JsonResponse
    {
        $project = Project::where('tenant_id', $request->user()->tenant_id)->findOrFail($id);
        $this->projects->triggerSync($project);

        return response()->json(['queued' => true, 'sync_status' => 'pending'], 202);
    }

    /** PATCH /api/projects/{id}/toggle-active — flip is_active flag */
    public function toggleActive(Request $request, int $id): JsonResponse
    {
        $request->validate(['is_active' => ['required', 'boolean']]);
        $project = Project::where('tenant_id', $request->user()->tenant_id)->findOrFail($id);
        $project->update(['is_active' => $request->boolean('is_active')]);

        return response()->json(['data' => new ProjectResource($project->fresh())]);
    }

    /** POST /api/projects/bulk — batch pause/resume/archive/update_regions/update_days/update_limit */
    public function bulk(BulkProjectActionRequest $request): JsonResponse
    {
        $tenantId = $request->user()->tenant_id;
        $ids = $this->projects->resolveBulkScope(
            $tenantId,
            $request->validated('ids'),
            $request->validated('scope.filter'),
        );

        if (count($ids) > ProjectService::BULK_MAX) {
            return response()->json([
                'errors' => ['scope' => ['Слишком много проектов под фильтр (>500). Уточните фильтры или выберите вручную.']],
            ], 422);
        }

        $payload = array_merge($request->validated(), ['ids' => $ids]);

        $result = $this->projects->bulkAction($tenantId, $request->validated('action'), $payload);

        return response()->json($result);
    }
}
