<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Repositories\PedidoTrackingRepository;
use App\Repositories\RepartidorRepository;
use App\Services\TrackingService;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as Request;

class TrackingController
{
    private TrackingService $trackingService;
    private PedidoTrackingRepository $repository;
    private RepartidorRepository $repartidores;

    public function __construct(
        TrackingService $trackingService,
        PedidoTrackingRepository $repository,
        RepartidorRepository $repartidores
    ) {
        $this->trackingService = $trackingService;
        $this->repository = $repository;
        $this->repartidores = $repartidores;
    }

    /**
     * Recibe la ubicación GPS enviada por la app Repartidor (en segundo plano o foreground).
     */
    public function registrarUbicacion(Request $request, Response $response, array $args): Response
    {
        $pedidoId = (int) $args['id'];
        $usuarioId = (int) $request->getAttribute('usuario_id');
        $repartidor = $this->repartidores->buscarPorUsuarioId($usuarioId);

        if (!$repartidor) {
            return $this->json($response, ['error' => 'El usuario autenticado no es un repartidor'], 403);
        }

        $repartidorId = (int) $repartidor['id'];
        $body = (array) $request->getParsedBody();

        foreach (['lat', 'lng'] as $campo) {
            if (!isset($body[$campo]) || !is_numeric($body[$campo])) {
                return $this->json($response, ['error' => "El campo {$campo} es requerido y debe ser numérico"], 422);
            }
        }

        $this->trackingService->registrarUbicacion(
            $pedidoId,
            $repartidorId,
            (float) $body['lat'],
            (float) $body['lng'],
            isset($body['rumbo']) ? (float) $body['rumbo'] : null,
            isset($body['velocidad']) ? (float) $body['velocidad'] : null
        );

        return $this->json($response, ['ok' => true]);
    }

    /**
     * Endpoint público (sin JWT, protegido por token del pedido a nivel de ruta)
     * usado por la web de seguimiento para pintar la última posición y el historial.
     */
    public function verUbicacion(Request $request, Response $response, array $args): Response
    {
        $pedidoId = (int) $args['id'];

        return $this->json($response, [
            'ultima' => $this->repository->ultimaUbicacion($pedidoId),
            'historial' => $this->repository->historial($pedidoId),
        ]);
    }

    private function json(Response $response, array $data, int $status = 200): Response
    {
        $response->getBody()->write(json_encode($data));

        return $response->withHeader('Content-Type', 'application/json')->withStatus($status);
    }
}
