<?php

declare(strict_types=1);

namespace App\Http\Controllers\Api\Pwa;

use App\Http\Controllers\Api\Pwa\Traits\RoleAwareQueries;
use App\Http\Controllers\Controller;
use App\Models\SupervisorCollector;
use App\Models\User;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;

class SupervisorTeamController extends Controller
{
    use RoleAwareQueries;

    // ------------------------------------------------------------------
    // GET /api/pwa/team/collectors
    // ------------------------------------------------------------------

    /**
     * Lista todos los collectors de la empresa disponibles para asignar.
     * Solo accesible para admin.
     */
    public function collectors(Request $request): JsonResponse
    {
        if ($this->getUserPwaRole($request) !== 'admin') {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $companyId = $request->user()->company_id;

        $collectors = User::role('collector')
            ->where('users.company_id', $companyId)
            ->select(['users.id', 'users.name', 'users.email', 'users.phone'])
            ->orderBy('users.name')
            ->get()
            ->map(fn (User $c) => [
                'id' => $c->id,
                'name' => $c->name,
                'email' => $c->email,
                'phone' => $c->phone,
            ]);

        return response()->json(['data' => $collectors]);
    }

    // ------------------------------------------------------------------
    // POST /api/pwa/team/supervisors/{supervisorId}/collectors
    // ------------------------------------------------------------------

    /**
     * Asigna un collector a un supervisor.
     * Solo accesible para admin.
     *
     * Body: { "collector_id": int }
     */
    public function assignCollector(Request $request, int $supervisorId): JsonResponse
    {
        if ($this->getUserPwaRole($request) !== 'admin') {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $admin = $request->user();
        $companyId = $admin->company_id;

        $validated = $request->validate([
            'collector_id' => ['required', 'integer'],
        ]);

        // Verificar que el supervisor existe, pertenece a esta empresa y tiene rol adecuado.
        $supervisor = User::where('id', $supervisorId)
            ->where('company_id', $companyId)
            ->first();

        if (! $supervisor || ! $supervisor->hasAnyRole(['supervisor', 'admin'])) {
            return response()->json(['message' => 'Supervisor no encontrado en esta empresa.'], 404);
        }

        // Verificar que el collector existe y pertenece a esta empresa.
        $collector = User::where('id', $validated['collector_id'])
            ->where('company_id', $companyId)
            ->first();

        if (! $collector || ! $collector->hasRole('collector')) {
            return response()->json(['message' => 'Cobrador no encontrado en esta empresa.'], 404);
        }

        // Verificar que no exista ya la asignación (evitar error de unique constraint).
        $alreadyAssigned = SupervisorCollector::where('supervisor_id', $supervisorId)
            ->where('collector_id', $validated['collector_id'])
            ->where('company_id', $companyId)
            ->exists();

        if ($alreadyAssigned) {
            return response()->json(['message' => 'El cobrador ya está asignado a este supervisor.'], 422);
        }

        // attach() con ->using(SupervisorCollector::class) va por attachUsingCustomClass()
        // → newPivot()->save() → dispara el evento creating en SupervisorCollector.
        // El booted() listener inyecta company_id desde el supervisor si no viene explícito.
        // Lo pasamos explícito de todas formas como segunda capa de seguridad.
        $supervisor->assignedCollectors()->attach(
            $validated['collector_id'],
            ['company_id' => $companyId]
        );

        return response()->json([
            'message' => 'Cobrador asignado correctamente.',
            'supervisor_id' => $supervisorId,
            'collector_id' => $validated['collector_id'],
        ], 201);
    }

    // ------------------------------------------------------------------
    // DELETE /api/pwa/team/supervisors/{supervisorId}/collectors/{collectorId}
    // ------------------------------------------------------------------

    /**
     * Desasigna un collector de un supervisor.
     * Solo accesible para admin.
     */
    public function unassignCollector(Request $request, int $supervisorId, int $collectorId): JsonResponse
    {
        if ($this->getUserPwaRole($request) !== 'admin') {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $companyId = $request->user()->company_id;

        // Verificar multi-tenancy: el registro debe pertenecer a esta empresa.
        $deleted = SupervisorCollector::where('supervisor_id', $supervisorId)
            ->where('collector_id', $collectorId)
            ->where('company_id', $companyId)
            ->delete();

        if (! $deleted) {
            return response()->json(['message' => 'Asignación no encontrada.'], 404);
        }

        return response()->json(['message' => 'Cobrador desasignado correctamente.']);
    }

    // ------------------------------------------------------------------
    // PATCH /api/pwa/team/supervisors/{supervisorId}
    // ------------------------------------------------------------------

    /**
     * Actualiza el flag sees_all_collectors de un supervisor.
     * Solo accesible para admin.
     *
     * Body: { "sees_all_collectors": bool }
     */
    public function updateSupervisor(Request $request, int $supervisorId): JsonResponse
    {
        if ($this->getUserPwaRole($request) !== 'admin') {
            return response()->json(['message' => 'No autorizado.'], 403);
        }

        $companyId = $request->user()->company_id;

        $validated = $request->validate([
            'sees_all_collectors' => ['required', 'boolean'],
        ]);

        $supervisor = User::where('id', $supervisorId)
            ->where('company_id', $companyId)
            ->first();

        if (! $supervisor || ! $supervisor->hasAnyRole(['supervisor', 'admin'])) {
            return response()->json(['message' => 'Supervisor no encontrado en esta empresa.'], 404);
        }

        $supervisor->update(['sees_all_collectors' => $validated['sees_all_collectors']]);

        return response()->json([
            'message' => 'Configuración actualizada.',
            'supervisor_id' => $supervisorId,
            'sees_all_collectors' => $supervisor->sees_all_collectors,
        ]);
    }
}
