<?php

namespace App\Controller;

use App\Entity\CoastalPoint;
use App\Entity\UserFeedback;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/api/feedback', name: 'api_feedback_')]
class FeedbackController extends AbstractController
{
    public function __construct(
        private EntityManagerInterface $em,
        private RateLimiterFactory $apiFeedbackLimiter,
    ) {}

    /**
     * POST /api/feedback
     *
     * Corps attendu :
     * {
     *   "lat": 14.65,
     *   "lng": -61.05,
     *   "hasSeaweed": true,
     *   "density": "medium",      // optionnel : low|medium|high
     *   "coastalPointId": "uuid"  // optionnel
     * }
     */
    #[Route('', name: 'create', methods: ['POST'])]
    public function create(Request $request): JsonResponse
    {
        $limiter = $this->apiFeedbackLimiter->create($request->getClientIp() ?? 'unknown');
        if (!$limiter->consume()->isAccepted()) {
            return $this->json(['error' => 'Too many requests'], 429);
        }

        $data = json_decode($request->getContent(), true);

        if (!is_array($data)) {
            return $this->json(['error' => 'Invalid JSON body'], 400);
        }

        // Validation minimale
        if (!isset($data['lat'], $data['lng'], $data['hasSeaweed'])) {
            return $this->json(['error' => 'Missing required fields: lat, lng, hasSeaweed'], 422);
        }

        $lat = filter_var($data['lat'], FILTER_VALIDATE_FLOAT);
        $lng = filter_var($data['lng'], FILTER_VALIDATE_FLOAT);

        if ($lat === false || $lng === false) {
            return $this->json(['error' => 'lat and lng must be valid floats'], 422);
        }

        if ($lat < -90 || $lat > 90 || $lng < -180 || $lng > 180) {
            return $this->json(['error' => 'lat/lng out of valid range'], 422);
        }

        $feedback = new UserFeedback();
        $feedback->setLocation(sprintf('SRID=4326;POINT(%f %f)', $lng, $lat));
        $feedback->setHasSeaweed((bool) $data['hasSeaweed']);

        if (isset($data['density']) && in_array($data['density'], ['low', 'medium', 'high'], true)) {
            $feedback->setDensity($data['density']);
        }

        // Fingerprint anonyme : IP hachée (pas de données personnelles)
        $ip = $request->getClientIp() ?? 'unknown';
        $feedback->setSource(hash('sha256', $ip . date('Y-m-d')));

        if (!empty($data['coastalPointId'])) {
            $spot = $this->em->getRepository(CoastalPoint::class)->find($data['coastalPointId']);
            if ($spot !== null) {
                $feedback->setCoastalPoint($spot);
            }
        }

        $this->em->persist($feedback);
        $this->em->flush();

        return $this->json(['id' => (string) $feedback->getId()], 201);
    }
}
